import { Breadcrumb, Button, Card, Form, Input, message, Modal, Radio, Space, Upload } from 'antd';
import React, { useEffect, useRef, useState } from 'react';
import { Link, useParams } from 'react-router-dom';
//下拉框频道组件
import Channel from "components/Channel"
//引入富文本编辑器
import ReactQuill from 'react-quill';
import 'react-quill/dist/quill.snow.css';
//引入module.scss样式文件
import styles from './index.module.scss'
import { PlusOutlined } from '@ant-design/icons';
import { baseURL } from 'utils/request';
import { getToken } from 'utils/storage';
import { addArticles, editArticles, getArticlesByIdAPI } from 'api/article';
import { useHistory } from 'react-router-dom';



export default function ArticlePublish(){
  
  

  //创建ref保存draft的值
  const draft= useRef(false)
   //通过useHistory获取history
   //获取history的三种方式区别
  //  1.通过封装函数history.js :没有限制
  //  2.props.history : Route组件设置过匹配路由的,才有props.history
  //  3.useHistory: 没有设置过匹配路由的,也可以使用   推荐
   const history = useHistory()
   //声明状态保存单选框图片选择数
   const [type, setType] = useState(1)
   // 声明状态保存上传后的图片base64位编码url
   const [imgUrl, setImgUrl] = useState('')
   //设置上传文件类型白名单
  const imgWhiteType = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif']
  //声明状态保存上传数据fileList 用于驱动视图
  const [fileList, setFileList] = useState([])

   //使用useParams获取路由ID   
   const params =useParams()
   const {id}=params   //需要结构什么事根据路由设置的后缀是什么
  //创建ref绑定form表单获取实例对象回显数据
   const formRef = useRef()
   //根据id获取文章详情封装函数 
   const loadArticleById=async(id)=>{
    const res = await getArticlesByIdAPI(id)
    const type = res.data.cover.type
    //根据挂载在form表单的ref调取实例对象setFieldsValue传值回显数据
    formRef.current.setFieldsValue({...res.data,type})
    //type值回传,为了控制图片数量和上传组件的显示
    setType(type)
    // 回显图片
    setFileList(res.data.cover.images.map(item=>({url:item})))
  }
  //挂载时根据有无id调取获取文章详情封装函数
     useEffect(() => {
       if(id){
         loadArticleById(id)
       }
     // eslint-disable-next-line react-hooks/exhaustive-deps
     }, [])
     
  const props = {
      //文件上传的类型
      name: 'image',
      //显示默认支持的文件上传
      accept:'.jpeg,.png,.jpg,.gif',
      //上传文件的接口地址
      action: `${baseURL}/v1_0/upload`,
      //添加token
      headers: {
        authorization:`Bearer${getToken()}`,
      },
      onChange(info) {
       //每次上传组件发生改变保存info.fileList  并把它传给组件,传给组件是为了之后编辑功能图片回显
       setFileList(info.fileList)

      //上传成功失败判定并提示用户
        if (info.file.status === 'done') {
          message.success('文件上传成功');
        } else if (info.file.status === 'error') {
          message.error('文件上传失败');
        }
      },

      // 上传成功后回调函数,点击预览触发事件,接收上传图片的数据
      onPreview(file){
         console.log('file  ----->  ', file);
      //  逻辑或   file中有url代表是回显数据,否则就是file中base64位编码的url,根据url显示预览图片   
         setImgUrl(file.url||file.thumbUrl)
      },


      //上传前的回调函数,返回file和fileList,file.type会有上传文件类型标注
      beforeUpload(file){
          // 判定返回的file.type文件类型不包含在上传文件白名单上返回false
          if(!imgWhiteType.includes(file.type)){
              // 提示用户
             message.warning('只能上传图片类型文件')
              //停止上传动作,并不让其显示在页面
             return Upload.LIST_IGNORE
          }
       } 
    };
     
    //表单数据发生改变触发事件
    const handleValuesChange=(changedValues, allValues)=>{
      // changedValues  监听单个数据发生改变   是一个对象，改变哪个字段，对象中就只有哪个键
      // allValues      监听整个表单数据
      if(changedValues.type !== undefined){
         setType(changedValues.type)

      }
    }

    // 定义控制图片显示的计算属性
    const showFileList = fileList.filter((item, index) => {
      if(type===0) return false
      if(type===1) return index===0
      return true
    })
    
    //提交Form表单事件
    const handleSubmit=async(values)=>{
      //  console.log('values  ----->  ', values);
      const fromData = {...values}
       //添加fromData的cover
      fromData.cover={
        type,
        //item.url代表是修改文章的图片,item.response.data.url代表是新增文章上传的图片地址数组
        images: type===0?[]:showFileList.map(item=>item.url||item.response.data.url)
      }
       delete fromData.type

       //判断选择的type数量和fileList长度是否相等,不相等提示用户
       if(fileList.length < type){
          message.warning('图片数量不对,请继续上传')
          return
       }
       try {
         //判定是否有id,有的话是修改,调修改接口,没有的话调发布接口
         if(id){
          //  调用修改文章接口
         await  editArticles({id,...fromData},draft.current)
         message.success('修改成功',1)

         }else{
          //调用发布文章接口
         //draft.current通过事件冒泡传入
         await addArticles(fromData,draft.current)
         // 提示用户
         message.success('发布成功',1)
         }
        
         //跳转路由
         history.push('/list')
         
       } catch (error) {
         message.warning('发布失败')
       }
       
    }
  return (
    <div style={{paddingTop:24}} className={styles.publish}>
      <Card
        title={
          <Breadcrumb>
            <Breadcrumb.Item>
              <Link to="/home">首页</Link>
            </Breadcrumb.Item>
            <Breadcrumb.Item>{id?'编辑':'发布'}文章</Breadcrumb.Item>
          </Breadcrumb>
        }
      >
        <Form
        ref={formRef}
         size="large"
          name="basic"
          labelCol={{
            span: 4,
          }}
          wrapperCol={{
            span: 20,
          }}
          autoComplete="off"
          onFinish={handleSubmit}
          // {/* 富文本设置了name属性要配合初始值 */}
          initialValues={{content:'', type: 1}}
          //数据更新触发事件
          onValuesChange={handleValuesChange}
        >
          {/* 标题 */}
          <Form.Item 
          label="标题" 
          name="title" 
           rules={[
            {
              required: true,
              message: '标题不能为空!',
            },
          ]}>
            <Input />
          </Form.Item>

          {/* 频道 */}
          <Form.Item 
          label="频道" 
          name="channel_id" 
           rules={[
          {
            required: true,
            message: '频道不能为空!',
          },
        ]}>
            <Channel style={{ width: 300 }}></Channel>
          </Form.Item>

          
          {/* 富文本设置了name属性要配合初始值 */}
          <Form.Item 
          label="内容" 
          name="content"  
          rules={[
          {
            required: true,
            message: '文章内容不能为空!',
          },
          {
            validator:(_,value)=>{
              //  console.log('value  ----->  ', value);
              if(value === '<p><br></p>'){
                 return Promise.reject(new Error('内容不能为空'))
              }
              return Promise.resolve()
            },
            message: '文章内容不能为空!',
          },
        ]}>
            {/* 受控组件  FormItem会自动控制ReactQuill为受控组件 */}
              <ReactQuill></ReactQuill>
          </Form.Item>
           
           {/* 封面单选框 */}
          <Form.Item label="封面" name="type">
            <Radio.Group>
               <Radio value={1}>单图</Radio>
               <Radio value={3}>三图</Radio>
               <Radio value={0}>无图</Radio>
            </Radio.Group>
          </Form.Item>
           {/* 上传图片组价 */}
          <Form.Item wrapperCol={{ offset: 4 }}>
              <Upload {...props} listType="picture-card" fileList={showFileList}>
                 {   
                   // 判定小于type时显示,小于等于type显示组件
                   fileList.length < type && <Button icon={<PlusOutlined />}></Button>
                  } 
              </Upload>
          </Form.Item>

          <Form.Item
            wrapperCol={{
              // 💥 从左向右偏移量
              offset: 4,
              // span: 16,
            }}
          >
            <Space>
              <Button type="primary" htmlType="submit">
              {id?'编辑':'发布'}文章
              </Button>

              <Button type="primary" htmlType="submit" onClick={()=>draft.current = true}>
                存草稿
              </Button>
            </Space>
          </Form.Item>
        </Form>
      </Card>

        {/* visible={!!imgUrl}   控制显示   !! 代表强制转换布尔类型  onCancel   antd模态框自带api   点击X触发    footer={null}代表不需要底部确认取消按钮  */}
      <Modal title="图片预览" visible={!!imgUrl} onCancel={()=>setImgUrl('')} footer={null} centered>
           <img width={400} style={{marginLeft:35}} src={imgUrl} alt="" />
       </Modal>
    </div>
  )
}
